package cn.szabadsag.order.service.impl;

import cn.szabadsag.base.constant.JobConstants;
import cn.szabadsag.base.constant.OrderConstant;
import cn.szabadsag.base.service.impl.BaseServiceImpl;
import cn.szabadsag.order.domain.OrderAddress;
import cn.szabadsag.order.domain.OrderAdopt;
import cn.szabadsag.order.mapper.OrderAddressMapper;
import cn.szabadsag.order.mapper.OrderAdoptMapper;
import cn.szabadsag.order.service.IOrderAdoptService;
import cn.szabadsag.pay.domain.PayBill;
import cn.szabadsag.pay.mapper.PayBillMapper;
import cn.szabadsag.pay.service.IPayService;
import cn.szabadsag.pet.domain.Pet;
import cn.szabadsag.pet.mapper.PetMapper;
import cn.szabadsag.quartz.domain.QuartzJobInfo;
import cn.szabadsag.quartz.service.IQuartzService;
import cn.szabadsag.user.domain.User;
import cn.szabadsag.user.domain.UserAddress;
import cn.szabadsag.user.mapper.UserAddressMapper;
import cn.szabadsag.utils.AjaxResult;
import cn.szabadsag.utils.CodeGenerateUtils;
import cn.szabadsag.utils.LoginContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yangcong
 * @date 2022年03月18日 12:56
 * @since
 */
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class OrderAdoptServiceImpl extends BaseServiceImpl<OrderAdopt> implements IOrderAdoptService {

    @Autowired
    private PetMapper petMapper;
    
    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;

    @Autowired
    private OrderAdoptMapper orderAdoptMapper;

    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private IPayService payService;

    @Autowired
    private IQuartzService quartzService;


    /**
     * 创建订单
     * @param map 前端参数
     */
    @Override
    public AjaxResult createOrder(Map<String, String> map, HttpServletRequest request) {
        //  获取前端参数
        /*
        "addressId":1,
        "payway":"ALIPAY",
        "petId":4
         */
        Long petId = Long.valueOf(map.get("petId"));
        Long addressId = Long.valueOf(map.get("addressId"));
        String payway = map.get("payway");
        //  获取当前登录的用户的信息
        User user = (User)LoginContext.getCurrentUser(request);
        System.out.println("登录用户的数据：" + user);
        /*
            1.更改下单宠物的状态
            2.生成一个OrderAdopt对象
            3.根据addressId 查询对应的UserAddress
            4.生成一个OrderAddress
            5.保存 OrderAdopt  OrderAddress
            6.根据订单生成对应的支付订单
         */

        //  1.更改下单宠物的状态
        //  查询当前下单的宠物
        Pet pet = petMapper.loadById(petId);
        //  2表示已售出
        pet.setState(2);
        //  同步当前下单的宠物状态到数据库
        petMapper.update(pet);


        //  2.生成一个OrderAdopt对象
        OrderAdopt orderAdopt = createOrderAdopt(pet, user);
        //  3.根据addressId 查询对应的UserAddress
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        //  4.生成一个OrderAddress
        OrderAddress orderAddress = userAddress2OrderAddress(userAddress);
        //  关联数据
        orderAddress.setOrderSn(orderAdopt.getOrderSn());
        //  5.保存 OrderAdopt  OrderAddress
        orderAddressMapper.save(orderAddress);
        orderAdopt.setAddress_id(orderAddress.getId());
        orderAdoptMapper.save(orderAdopt);


        //  6.根据订单生成对应的支付订单
        PayBill payBill = orderAdopt2PayBill(orderAdopt);
        //  设置订单支付方式
        payBill.setPayChannel(payway);
        //  保存支付订单数据
        payBillMapper.save(payBill);

        //  8.创建定时任务
        QuartzJobInfo quartzJobInfo = new QuartzJobInfo();
        //  设置类型
        quartzJobInfo.setType(JobConstants.JOB_TYPE_ADOPT_ORDER_CANCEL);
        //  设置jobName
        String jobName = JobConstants.ADOPT_ORDER_CANCEL_PREFIX + orderAdopt.getId();
        quartzJobInfo.setJobName(jobName);
        //  传递参数
        Map<String, Object> orderCancelParams = new HashMap<>();
        orderCancelParams.put("orderId",orderAdopt.getId());
        quartzJobInfo.setParams(orderCancelParams);
        //  最后支付时间/触发时间
        quartzJobInfo.setFireDate(orderAdopt.getLastPayTime());
        quartzService.addJob(quartzJobInfo);
        System.out.println(jobName + "被添加了!");

        //  7.支付宝下单
        String pay = payService.pay(payBill);
        System.out.println(pay);
        return AjaxResult.me().setResultObj(pay);
    }

    /**
     * 订单取消
     * @param orderId
     */
    @Override
    public void cancelByQuartz(Long orderId) {
        OrderAdopt adoptOrder = orderAdoptMapper.loadById(orderId);
        //订单状态要改
        adoptOrder.setState(-1);
        orderAdoptMapper.update(adoptOrder);

        //6.上架宠物
        petMapper.onsale(Arrays.asList(adoptOrder.getPet_id()));

        //支付单也要修改
        //String paySn = adoptOrder.getPaySn();
        //PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        String orderSn = adoptOrder.getOrderSn();
        PayBill payBill = payBillMapper.loadByOrderSn(orderSn);
        payBill.setState(-1);
        payBillMapper.update(payBill);

        System.out.println(adoptOrder.getDigest()+"被quartz自动取消了！");
    }

    /**
     * 将OrderAdopt对象转化为PayBill对象
     * @param orderAdopt
     * @return
     */
    private PayBill orderAdopt2PayBill(OrderAdopt orderAdopt) {
        PayBill payBill = new PayBill();
        BeanUtils.copyProperties(orderAdopt,payBill);
        //  设置金额
        payBill.setMoney(orderAdopt.getPrice());
        //  订单类型 设置为领养订单
        payBill.setBusinessType(OrderConstant.ORDER_ADOPT);
        //  订单主键
        payBill.setBusinessKey(orderAdopt.getId());
        return payBill;
    }

    /**
     * 将UserAddress对象转化为OrderAddress对象
     * @param userAddress
     * @return
     */
    private OrderAddress userAddress2OrderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        return orderAddress;
    }

    /**
     * 创建一个OrderAdopt对象
     * @return
     */
    private OrderAdopt createOrderAdopt(Pet pet, User user) {
        OrderAdopt orderAdopt = new OrderAdopt();
        //  摘要
        orderAdopt.setDigest("[宠物之家]-领养订单");
        //  0表示待支付
        orderAdopt.setState(0);
        orderAdopt.setPrice(pet.getSaleprice());
        //  订单编号：唯一不重复，全是数字
        orderAdopt.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        System.out.println("订单编号：" + orderAdopt.getOrderSn());
        // private String paySn;
        // private Date lastPayTime;
        //  订单30分钟后失效，设置最后支付时间
        //orderAdopt.setLastPayTime(new Date(System.currentTimeMillis() + 1000*60*30));
        orderAdopt.setLastPayTime(new Date(System.currentTimeMillis() + 1000*60*1));
        orderAdopt.setPet_id(pet.getId());
        orderAdopt.setUser_id(user.getId());
        orderAdopt.setShop_id(pet.getShop_id());
        // private Long address_id;
        return orderAdopt;
    }
}
